use crate::rtsp::rtp::rtp_header::RtpHeader;
use crate::rtsp::rtp::utils::{Marshal, Unmarshal};
use byteorder::BigEndian;
use bytes::{BufMut, BytesMut};
use bytesio::bytes_errors::{BytesReadError, BytesWriteError};
use bytesio::bytes_reader::BytesReader;
use bytesio::bytes_writer::BytesWriter;

pub mod define;
pub mod errors;
pub mod rtcp;
pub mod rtp_aac;
pub mod rtp_h264;
pub mod rtp_h265;
pub mod rtp_header;
pub mod utils;

#[derive(Debug, Clone, Default)]
pub struct RtpPacket {
    // RTP 头
    pub header: RtpHeader,
    // 配置文件标识符
    pub header_extension_profile: u16,
    // 扩展的长度
    pub header_extension_length: u16,
    // 具体负载数据
    pub header_extension_payload: BytesMut,
    // RTP 数据包的有效负载数据
    pub payload: BytesMut,
    // 填充数据
    pub padding: BytesMut,
}

impl Unmarshal<&mut BytesReader, Result<Self, BytesReadError>> for RtpPacket {
    // 将字节流反序列化为 RtpPacket 实例的具体实现
    // 参考文档：https://blog.jianchihu.net/webrtc-research-rtp-header-extension.html
    fn unmarshal(reader: &mut BytesReader) -> Result<Self, BytesReadError>
    where
        Self: Sized,
    {
        // 首先反序列化 RTP 头部
        let mut rtp_packet = RtpPacket {
            header: RtpHeader::unmarshal(reader)?,
            ..Default::default()
        };

        // 如果头部的扩展标志位为 1，表示存在头部扩展
        if rtp_packet.header.extension_flag == 1 {
            // 头部扩展的格式如下：
            // 0                   1                   2                   3
            // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
            // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            // |      defined by profile       |           length              |
            // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            // |                        header extension                       |
            // |                             ....                              |
            // header_extension = profile(2 bytes) + length(2 bytes) + header extension payload
            // 读取头部扩展的配置文件标识符
            rtp_packet.header_extension_profile = reader.read_u16::<BigEndian>()?;
            // 读取头部扩展的长度
            rtp_packet.header_extension_length = reader.read_u16::<BigEndian>()?;
            // 读取头部扩展的具体负载数据，长度为 4 乘以扩展长度（因为长度是以 32 位字为单位）
            rtp_packet.header_extension_payload =
                reader.read_bytes(4 * rtp_packet.header_extension_length as usize)?;
        }

        // 如果头部的填充标志位为 1，表示存在填充数据
        if rtp_packet.header.padding_flag == 1 {
            // 最后一个字节表示填充数据的长度
            let padding_length = reader.get(reader.len() - 1)? as usize;
            // 读取有效负载数据，排除填充数据
            rtp_packet
                .payload
                .put(reader.read_bytes(reader.len() - padding_length)?);
            // 读取填充数据
            rtp_packet.padding.put(reader.read_bytes(padding_length)?);
        } else {
            // 如果没有填充数据，将剩余的所有字节作为有效负载
            rtp_packet.payload.put(reader.extract_remaining_bytes());
        }

        // 返回反序列化后的 RtpPacket 实例
        Ok(rtp_packet)
    }
}

impl Marshal<Result<BytesMut, BytesWriteError>> for RtpPacket {
    fn marshal(&self) -> Result<BytesMut, BytesWriteError> {
        // 创建一个字节写入器
        let mut writer = BytesWriter::new();

        // 序列化 RTP 头部
        let header_bytesmut = self.header.marshal()?;
        // 将序列化后的头部写入字节写入器
        writer.write(&header_bytesmut[..])?;

        // 如果存在头部扩展
        if self.header.extension_flag == 1 {
            // 写入头部扩展的配置文件标识符
            writer.write_u16::<BigEndian>(self.header_extension_profile)?;
            // 写入头部扩展的长度
            writer.write_u16::<BigEndian>(self.header_extension_length)?;
            // 写入头部扩展的具体负载数据
            writer.write(&self.header_extension_payload[..])?;
        }

        // 写入有效负载数据
        writer.write(&self.payload[..])?;
        // 如果存在填充数据
        if self.header.padding_flag == 1 {
            // 写入填充数据
            writer.write(&self.padding[..])?;
        }

        // 返回序列化后的字节流
        Ok(writer.extract_current_bytes())
    }
}

impl RtpPacket {
    fn new(header: RtpHeader) -> Self {
        Self {
            header,
            ..Default::default()
        }
    }
}
